#ifndef __ICE_TRANSPORT_CHANNEL_H
#define __ICE_TRANSPORT_CHANNEL_H
#include <string>
#include <memory>
#include <rtc_base/third_party/sigslot/sigslot.h>
#include "base/event_loop.h"
#include "ice/ice_def.h"
#include "ice/port_allocator.h"
#include "ice/ice_credentials.h"
#include "ice/candidate.h"
#include "ice/stun.h"
#include "ice/ice_controller.h"
namespace xrtc
{
    class UDPPort;
    enum class IceTransportState
    {

        kNew,
        kChecking,
        kConnected,
        kCompleted,
        kFailed,
        kDisconnected,
        kClosed,

    };
    class IceTransportChannel : public sigslot::has_slots<>
    {
    public:
        IceTransportChannel(EventLoop *el, PortAllocator *allocator, const std::string &transport_name_, IceCandidateComponent component);
        virtual ~IceTransportChannel();
        const std::string &TransportName() { return transport_name_; }
        IceCandidateComponent Component() { return component_; }
        void GatheringCandidate(); // 收集candidate
        void SetIceParams(const IceParameters &ice_params);
        void SetRemoteIceParams(const IceParameters &ice_params);
        bool Writable() { return writable_; }
        bool Receiving() { return receiving_; }
        IceTransportState State() {return state_;}
        int SendPacket(const char *data, size_t data_len);

        sigslot::signal2<IceTransportChannel *, const std::vector<Candidate> &> SignalCandidateAllocateDone; /// signal2 其中2 代表参数格式
        sigslot::signal1<IceTransportChannel *> SignalReceivingState;
        sigslot::signal1<IceTransportChannel *> SignalWritableState;
        sigslot::signal1<IceTransportChannel *> SignalIceStateChanged;

        sigslot::signal4<IceTransportChannel *, const char *, size_t, int64_t> SignalReadPacket;

        std::string ToString();

    private:
        void OnUnknownAddress(UDPPort *port, const rtc::SocketAddress &addr, StunMessage *msg, const std::string &remote_ufrag);
        void SortConnectionAndUpdateState();
        void MaybeStartPinging();
        void AddConnection(IceConnection *conn);
        void OnCheckAndPing();
        void PingConnection(IceConnection *conn);
        void MaybeSwitchSelectedConnection(IceConnection *conn);
        void SwitchSelectedConnection(IceConnection *conn);
        IceTransportState ComputeIceTransportState();

        void UpdateConnectionStates();
        void UpdateState();
        void SetWritable(bool writable);
        void SetReceiving(bool receving);

        // 信号处理函数
        void OnConnectionDestoryed(IceConnection *conn);
        void OnConnectionStateChange(IceConnection *conn);
        void OnReadPacket(IceConnection * /*conn*/, const char *buf, size_t len, int64_t ts);

        friend void IcePingCb(EventLoop * /*el*/, TimerWatcher * /*w*/, void *data);

    private:
        EventLoop *el_;
        std::string transport_name_;
        IceCandidateComponent component_;
        PortAllocator *allocator_;

        // ice 参数信息
        IceParameters ice_params_;
        IceParameters remote_ice_params_;
        std::vector<Candidate> local_candidates_;
        std::vector<UDPPort*> ports_;
        // 连通性检测
        std::unique_ptr<IceController> ice_controller_;
        bool start_pinging_ = false;
        TimerWatcher *ping_watcher_ = nullptr;
        int64_t last_ping_sent_ms_ = 0;
        int cur_ping_interval_ = WEAK_PING_INTERVAL;
        IceConnection *selected_connection_ = nullptr;
        bool writable_ = false;
        bool receiving_ = false;
        IceTransportState state_ = IceTransportState::kNew;
        bool _had_connection = false; //是否创建过链接
        bool _has_been_connection = false;//是否成功的建立过链接（连通过）

    };

} // namespace xrtc

#endif